use crate::dto::*;
use crate::entity::*;
use crate::RB;
use hypers::prelude::{hypers_openapi, openapi, OpenApi, Responder, Response};
use rbatis::rbdc::datetime::DateTime;

pub struct Menu;

#[openapi(
    prefix = "/api",
    components(schemas(MenuListReq, MenuSaveReq, MenuUpdateReq, MenuDeleteReq))
)]
impl Menu {
    #[post("menu_list",tag = "查询菜单",request_body = MenuListReq)]
    async fn menu_list(item: MenuListReq) -> impl Responder {
        log::info!("menu_list params: {:?}", &item);
        // 菜单是树形结构不需要分页
        let result = SysMenu::select_all(&mut RB.clone()).await;
        let mut res = Response::default();
        match result {
            Ok(sys_menu_list) => {
                let mut list_data: Vec<MenuListData> = Vec::new();
                for menu in sys_menu_list {
                    list_data.push(MenuListData {
                        id: menu.id.unwrap(),
                        sort: menu.sort,
                        status_id: menu.status_id,
                        parent_id: menu.parent_id,
                        menu_name: menu.menu_name.to_string(),
                        label: menu.menu_name,
                        menu_url: menu.menu_url.unwrap_or_default(),
                        icon: menu.menu_icon.unwrap_or_default(),
                        api_url: menu.api_url.unwrap_or_default(),
                        remark: menu.remark.unwrap_or_default(),
                        menu_type: menu.menu_type,
                        create_time: menu.create_time.unwrap().0.to_string(),
                        update_time: menu.update_time.unwrap().0.to_string(),
                    })
                }
                res.json(&ok_result_page(list_data, 0));
                res
            }
            Err(err) => {
                log::error!("{}", err.to_string());
                res.json(&err_result_page(err.to_string()));
                res
            }
        };
    }

    #[post("menu_save",tag = "添加菜单",request_body = MenuSaveReq)]
    async fn menu_save(menu: MenuSaveReq) -> impl Responder {
        log::info!("menu_save params: {:?}", &menu);
        let sys_menu = SysMenu {
            id: None,
            create_time: Some(DateTime::now()),
            update_time: Some(DateTime::now()),
            status_id: menu.status_id,
            sort: menu.sort,
            parent_id: menu.parent_id,
            menu_name: menu.menu_name,
            menu_url: menu.menu_url,
            api_url: menu.api_url,
            menu_icon: menu.icon,
            remark: menu.remark,
            menu_type: menu.menu_type,
        };
        let result = SysMenu::insert(&mut RB.clone(), &sys_menu).await;
        handle_result(result)
    }

    #[post("menu_update",tag = "更新菜单",request_body = MenuUpdateReq)]
    async fn menu_update(menu: MenuUpdateReq) -> impl Responder {
        log::info!("menu_update params: {:?}", &menu);
        let sys_menu = SysMenu {
            id: Some(menu.id),
            create_time: None,
            update_time: Some(DateTime::now()),
            status_id: menu.status_id,
            sort: menu.sort,
            parent_id: menu.parent_id,
            menu_name: menu.menu_name,
            menu_url: menu.menu_url,
            api_url: menu.api_url,
            menu_icon: menu.icon,
            remark: menu.remark,
            menu_type: menu.menu_type,
        };
        let result = SysMenu::update_by_column(&mut RB.clone(), &sys_menu, "id").await;
        handle_result(result)
    }

    #[post("menu_delete",tag = "删除菜单信息",request_body = MenuDeleteReq)]
    async fn menu_delete(item: MenuDeleteReq) -> impl Responder {
        log::info!("menu_delete params: {:?}", &item);
        //有下级的时候 不能直接删除
        let menus = SysMenu::select_by_column(&mut RB.clone(), "parent_id", item.id)
            .await
            .unwrap_or_default();
        let mut res = Response::default();
        if menus.len() > 0 {
            res.json(&err_result_msg("有下级菜单,不能直接删除"));
            return res;
        }
        let result = SysMenu::delete_by_column(&mut RB.clone(), "id", item.id).await;
        res.json(&handle_result(result));
        res
    }
}
